home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Original Shareware 1.1
/
The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso
/
10
/
des.zip
/
DES.C
next >
Wrap
Text File
|
1989-08-27
|
12KB
|
402 lines
/*
* des.c
*
* Software Data Encryption Standard Implementation
*
* Version 2.4, February 25, 1985
*
* Permission is hereby given for non-commercial use.
*
* Copyright (c) 1977, 1984, 1985 By
* Jim Gillogly, Lauren Weinstein, and Richard Outerbridge
*/
#define DE 1
typedef char BYTE; /* BYTE = (vax) ? int : char */
void desinit(), p48init(), permute();
static char s12[4096], s34[4096], s56[4096], s78[4096];
static long p48a[256][2], p48b[256][2], p48c[256][2], p48d[256][2];
static long kn[32];
static int pmv[8] = {
64, 16, 4, 1, 128, 32, 8, 2
};
static int pvs[8] = {
1, 2, 4, 8, 16, 32, 64, 128
};
void des(inblock, outblock)
BYTE *inblock, *outblock;
{
register long *fmp, suba, subb, val, *h0L, *h1R, *keys;
BYTE scratch[8], *small;
long swap[4];
int i;
permute(inblock, pmv, pvs, scratch);
h0L = swap;
h1R = &swap[4];
small = scratch;
while (h0L < h1R) {
val = ((*small++) & 0377L) << 24;
val |= ((*small++) & 0377L) << 16;
val |= ((*small++) & 0377L) << 8;
val |= (*small++) & 0377L;
*h0L++ = ((val & 0x1L) << 23) | ((val >> 9) & 0x7C0000L) |
((val & 0x1F800000L) >> 11) |
((val & 0x1F80000L) >> 13) |
((val & 0x1F8000L) >> 15);
*h0L++ = ((val & 0x1F800L) << 7) |
((val & 0x1F80L) << 5) |
((val & 0x1F8L) << 3) |
((val & 0x1FL) << 1) |
((val >> 31) & 0x1L);
}
keys = kn;
h0L = swap;
h1R = &swap[2];
for (i = 0; i < 16; i++) {
val = *keys++ ^ *h1R++;
fmp = &p48a[ s12[(val >> 12)] & 0377 ][0];
suba = *fmp++;
subb = *fmp;
fmp = &p48b[ s34[(val & 07777L)] & 0377 ][0];
suba |= *fmp++;
subb |= *fmp;
val = *keys++ ^ *h1R++;
fmp = &p48c[ s56[(val >> 12)] & 0377 ][0];
suba |= *fmp++;
subb |= *fmp;
fmp = &p48d[ s78[(val & 07777L)] & 0377 ][0];
suba |= *fmp++;
subb |= *fmp;
*h0L++ ^= suba;
*h0L++ ^= subb;
if (i & 1)
h0L = swap;
else
h1R = swap;
}
val = *h0L;
*h0L++ = *h1R;
*h1R++ = val;
val = *h0L;
*h0L = *h1R;
*h1R = val;
h0L = swap;
h1R = &swap[4];
small = scratch;
while (h0L < h1R) {
*small++ = ((*h0L & 036000000L) >> 15) |
((*h0L & 0360000L) >> 13);
*small++ = ((*h0L & 03600L) >> 3) |
((*h0L & 036L) >> 1);
h0L++;
}
permute(scratch, pvs, pmv, outblock);
}
static char s1[64] = { /* S[1]<<4 */
224, 64,208, 16, 32,240,176,128, 48,160, 96,192, 80,144, 0,112,
0,240,112, 64,224, 32,208, 16,160, 96,192,176,144, 80, 48,128,
64, 16,224,128,208, 96, 32,176,240,192,144,112, 48,160, 80, 0,
240,192,128, 32, 64,144, 16,112, 80,176, 48,224,160, 0, 96,208
};
static char s3[64] = { /* S[3]<<4 */
160, 0,144,224, 96, 48,240, 80, 16,208,192,112,176, 64, 32,128,
208,112, 0,144, 48, 64, 96,160, 32,128, 80,224,192,176,240, 16,
208, 96, 64,144,128,240, 48, 0,176, 16, 32,192, 80,160,224,112,
16,160,208, 0, 96,144,128,112, 64,240,224, 48,176, 80, 32,192
};
static char s5[64] = { /* S[5]<<4 */
32,192, 64, 16,112,160,176, 96,128, 80, 48,240,208, 0,224,144,
224,176, 32,192, 64,112,208, 16, 80, 0,240,160, 48,144,128, 96,
64, 32, 16,176,160,208,112,128,240,144,192, 80, 96, 48, 0,224,
176,128,192,112, 16,224, 32,208, 96,240, 0,144,160, 64, 80, 48
};
static char s7[64] = { /* S[7]<<4 */
64,176, 32,224,240, 0,128,208, 48,192,144,112, 80,160, 96, 16,
208, 0,176,112, 64,144, 16,160,224, 48, 80,192, 32,240,128, 96,
16, 64,176,208,192, 48,112,224,160,240, 96,128, 0, 80,144, 32,
96,176,208,128, 16, 64,160,112,144, 80, 0,240,224, 32, 48,192
};
static char s2[64] = { /* S[2] */
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
};
static char s4[64] = { /* S[4] */
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
};
static char s6[64] = { /* S[6] */
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
};
static char s8[64] = { /* S[8] */
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
};
static char p48i[] = {
24, 15, 6, 19, 20, 28, 20, 28, 11, 27, 16, 0,
16, 0, 14, 22, 25, 4, 25, 4, 17, 30, 9, 1,
9, 1, 7, 23, 13, 31, 13, 31, 26, 2, 8, 18,
8, 18, 12, 29, 5, 21, 5, 21, 10, 3, 24, 15
};
static int bytebit[] = { /* bit 0 is left-most in byte */
0200,0100,040,020,010,04,02,01
};
static long bigbyte[] = {
0x800000L, 0x400000L, 0x200000L, 0x100000L,
0x80000L, 0x40000L, 0x20000L, 0x10000L,
0x8000L, 0x4000L, 0x2000L, 0x1000L,
0x800L, 0x400L, 0x200L, 0x100L,
0x80L, 0x40L, 0x20L, 0x10L,
0x8L, 0x4L, 0x2L, 0x1L
};
static int Ignited = 0;
void desinit()
{
register int j, left, right;
if (Ignited)
return;
for (j = 0; j < 4096; j++) {
left = ((j >> 6) & 040) | ((j >> 2) & 020) | ((j >> 7) & 017);
right = (j & 040) | ((j << 4) & 020) | ((j >> 1) & 017);
s12[j] = s1[left] | s2[right];
s34[j] = s3[left] | s4[right];
s56[j] = s5[left] | s6[right];
s78[j] = s7[left] | s8[right];
}
p48init();
Ignited = 1;
}
#ifdef KSX64
/* Implement an experimental, non-standard, simple-minded 64-bit key. */
void kinit(key, edf)
BYTE *key;
int edf;
{
register int i;
register long *tofill;
long master[16];
if (!Ignited)
desinit();
for (i = 0; i < 16; i++) {
master[i++] = (*key >> 4) & 017L;
master[i] = (*key++) & 017L;
}
for (i = 0; i < 16; i++) {
if (edf == DE)
tofill = &kn[(15 - i) << 1];
else
tofill = &kn[i << 1];
*tofill = (master[(i + 1) & 017] << 20);
*tofill |= (master[(i + 8) & 017] << 16);
*tofill |= (master[(i + 5) & 017] << 12);
*tofill |= (master[(i + 10) & 017] << 8);
*tofill |= (master[(i + 3) & 017] << 4);
*tofill++ |= master[(i + 14) & 017];
*tofill = (master[(i + 6) & 017] << 20);
*tofill |= (master[(i + 11) & 017] << 16);
*tofill |= (master[(i + 2) & 017] << 12);
*tofill |= (master[(i + 13) & 017] << 8);
*tofill |= (master[i] << 4);
*tofill |= master[(i + 9) & 017];
}
}
#else
/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
static char pc1[] = { /* permuted choice table (key) */
56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3
};
static char totrot[] = { /* number left rotations of pc1 */
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
};
static char pc2[] = { /* permuted choice key (table) */
13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52,
45, 41, 49, 35, 28, 31
};
void kinit(key, edf) /* initialize key schedule array*/
BYTE *key; /* 64 bits; we'll only use 56 */
int edf;
{
register int i, j, l, m, n;
char pc1m[56], pcr[56];
if (!Ignited)
desinit();
for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
l = pc1[j]; /* integer bit location */
m = l & 07; /* find bit */
pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
}
for (i = 0; i < 16; i++) { /* key chunk for each iteration */
if (edf == DE)
m = (15 - i) << 1;
else
m = i << 1;
n = m + 1;
kn[m] = kn[n] = 0L;
for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l - 28];
/* rotate left and right halves independently */
for (j = 0; j < 24; j++) {
if (pcr[pc2[j]])
kn[m] |= bigbyte[j];
if (pcr[pc2[j + 24]])
kn[n] |= bigbyte[j];
}
}
}
#endif
static void p48init() /* initialize 32-bit permutation */
{
register int l, j, k, i;
register long (*pfill)[2];
for (i = 0; i < 4; i++) { /* each input byte position */
switch (i) {
default:
break;
case 0:
pfill = p48a;
break;
case 1:
pfill = p48b;
break;
case 2:
pfill = p48c;
break;
case 3:
pfill = p48d;
}
for (j = 0; j < 256; j++) {
for (k = 0; k < 2; k++)
pfill[j][k] = 0L;
for (k = 0; k < 24; k++) {
l = p48i[k];
if ((l >> 3) != i)
continue;
if (!(j & bytebit[l & 07]))
continue;
pfill[j][0] |= bigbyte[k];
}
for (k = 24; k < 48; k++) {
l = p48i[k];
if ((l >> 3) != i)
continue;
if (!(j & bytebit[l & 07]))
continue;
pfill[j][1] |= bigbyte[k - 24];
}
}
}
}
static void permute(inblock, test, vals, outblock)
register BYTE *inblock;
int *test;
register int *vals;
BYTE *outblock;
{
register BYTE *cp, *eop, *eip;
register int *dp;
eop = &outblock[8];
eip = &inblock[8];
for (cp = outblock; cp < eop;)
*cp++ = 0;
while (inblock < eip) {
cp = outblock;
dp = test;
while (cp < eop) {
if (*inblock & *dp++)
*cp |= *vals;
cp++;
}
inblock++;
vals++;
}
}